﻿using System.Linq;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
using System.Windows.Media;
using Microsoft.Phone.Controls;
using Store.WP7.Framework.Extensions;
using System.Windows.Threading;
using System;
using Store.WP7.Framework.Animations;

namespace Store.WP7.Framework.Interactions
{
    /// <summary>
    /// Animates an element so that it flies out and flies in!
    /// </summary>
    public class ContinuumMasterBehavior : Behavior<ListBox>
    {
        #region TransitionBackground (DependencyProperty)

        /// <summary>
        /// A description of the property.
        /// </summary>
        public Brush TransitionBackground
        {
            get { return (Brush)GetValue(TransitionBackgroundProperty); }
            set { SetValue(TransitionBackgroundProperty, value); }
        }
        public static readonly DependencyProperty TransitionBackgroundProperty =
            DependencyProperty.Register("TransitionBackground", typeof(Brush), typeof(ContinuumMasterBehavior),
            new PropertyMetadata(null, new PropertyChangedCallback(OnTransitionBackgroundChanged)));

        private static void OnTransitionBackgroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ContinuumMasterBehavior)d).OnTransitionBackgroundChanged();
        }

        protected virtual void OnTransitionBackgroundChanged()
        {
            if (_animation != null)
                _animation.TransitionBackground = TransitionBackground;
        }

        #endregion


        private PhoneApplicationFrame rootVisual
        {
            get { return Application.Current.RootVisual as PhoneApplicationFrame; }
        }

        private ContinuumAnimation _animation;

        /// <summary>
        /// Constructor
        /// </summary>
        public ContinuumMasterBehavior()
        {
            // Default transition background is from the phone
            TransitionBackground = Application.Current.Resources["PhoneBackgroundBrush"] as Brush;
        }

        protected override void OnAttached()
        {
            base.OnAttached();

            AssociatedObject.Loaded += Page_Loaded;
            AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;

            OnTransitionBackgroundChanged();
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();

            AssociatedObject.Loaded -= Page_Loaded;
            AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            if (_animation == null)
                _animation = new ContinuumAnimation();

            _animation.MasterItemFlyIn();
        }

        void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var selectedItem = e.AddedItems.Count > 0 ? e.AddedItems[0] : null;
            if (selectedItem != null)
            {
                var container = AssociatedObject.ItemContainerGenerator.ContainerFromItem(selectedItem);

                var continuumItem = container.Descendants().FirstOrDefault(el => ContinuumAnimation.GetIsContinuumItem(el)) as FrameworkElement;
                if (continuumItem == null)
                {
                    continuumItem = container as FrameworkElement;
                }

                _animation.MasterItemFlyOut(continuumItem, () =>
                    {
                        AssociatedObject.SelectedItem = null;
                    });

                // Big disguting hack to hold on the navigation while 
                // processing the animation through the composition thread
                Dispatcher.BeginInvoke(() => Thread.Sleep((int)(ContinuumAnimation.FlyOutDuration * 1000)));
            }
        }
    }
}
